﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Xml;
using System.Xml.Linq;

using System.Threading;
using Microsoft.SharePoint.Client;

namespace NotificationPanel
{

    /// <summary>
    /// Notification Panel User Control
    /// </summary>
    public partial class MainPage : UserControl
    {

        // Private members...
        private ClientContext       _context        = null;
        private ListItemCollection  _notifications;
        private Web                 _web;
        private User                _currentUser;
        private Timer               _refreshTimer   = null;
        private int                 _timerValue     = ( 30 * 1000 );

        private ObservableCollection<NotificationMessage> _notificationDS = new ObservableCollection<NotificationMessage>();

        /// <summary>
        /// Initializes a new instance of the <see cref="MainPage"/> class.
        /// </summary>
        public MainPage()
        {
            InitializeComponent();

            _context = new ClientContext( ApplicationContext.Current.Url );
            _refreshTimer = new Timer( new TimerCallback( RefreshTimerEvent ) );

            InitializeData();
        }

        /// <summary>
        /// Initializes the data.
        /// </summary>
        private void InitializeData()
        {
            _web = _context.Web;
            _context.Load( _context.Web, s => s.CurrentUser );
            _context.ExecuteQueryAsync( new ClientRequestSucceededEventHandler( OnInitializeDataSucceeded ), new ClientRequestFailedEventHandler( OnInitializeDataFailed ) );
        }

        /// <summary>
        /// Called when [initialize data failed].
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="args">The <see cref="Microsoft.SharePoint.Client.ClientRequestFailedEventArgs"/> instance containing the event data.</param>
        private void OnInitializeDataFailed( Object sender, ClientRequestFailedEventArgs args )
        {

        }

        /// <summary>
        /// Called when [initialize data succeeded].
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="args">The <see cref="Microsoft.SharePoint.Client.ClientRequestSucceededEventArgs"/> instance containing the event data.</param>
        private void OnInitializeDataSucceeded( Object sender, ClientRequestSucceededEventArgs args )
        {
            _currentUser = _web.CurrentUser;

            _refreshTimer.Change( 0, _timerValue );
        }

        /// <summary>
        /// Handles the Click event of the btnRefresh control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>
        private void btnRefresh_Click( object sender, RoutedEventArgs e )
        {
            _refreshTimer.Change( 0, _timerValue );
        }

        /// <summary>
        /// Handles the Click event of the btnACK control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>
        private void btnACK_Click( object sender, RoutedEventArgs e )
        {
            List< NotificationMessage > msgs = new List<NotificationMessage>();
            foreach( object item in dgNotifications.SelectedItems )
            {
                msgs.Add( ( NotificationMessage )item );
            }


            foreach( object item in msgs )
            {
                _notificationDS.Remove( ( NotificationMessage )item );
            }

            Thread thread = new Thread( new ParameterizedThreadStart( AcknowledgeSelected ) );
            thread.Start( msgs );

        }

        /// <summary>
        /// Acknowledge the current selected notification items.
        /// </summary>
        /// <param name="param">The param.</param>
        private void AcknowledgeSelected( object param )
        {
            List< NotificationMessage > selectedMsgs = (List< NotificationMessage >) param;
            foreach( NotificationMessage msg in selectedMsgs )
            {
                List notifications = _context.Web.Lists.GetByTitle( "MASAS Notifications" );
                ListItem listItem = notifications.GetItemById( msg.ItemIdentifier );
                _context.Load( listItem );
                _context.ExecuteQuery();

                List<FieldUserValue> fieldUsers = null;
                if( listItem["Acknowledged"] == null )
                {
                    fieldUsers = new List<FieldUserValue>();
                }
                else
                {
                    fieldUsers = new List<FieldUserValue>( (FieldUserValue[])listItem["Acknowledged"] );
                }

                FieldUserValue fieldUser = new FieldUserValue();
                fieldUser.LookupId = _currentUser.Id;
                fieldUsers.Add( fieldUser );
                listItem["Acknowledged"] = fieldUsers.ToArray();

                listItem.Update();

                _context.ExecuteQuery();
            }

            _refreshTimer.Change( 0, _timerValue );
        }

        /// <summary>
        /// Timer event to refresh the data in the data grid.
        /// </summary>
        /// <param name="stateInfo">The state info.</param>
        private void RefreshTimerEvent( Object stateInfo )
        {
            List notifications = _context.Web.Lists.GetByTitle( "MASAS Notifications" );
            _context.Load( notifications );

            CamlQuery query = new CamlQuery();
            string camlQueryXml = @"<View><Query>
                                       <Where>
                                          <And>
                                             <Neq>
                                                <FieldRef Name='Acknowledged' />
                                                <Value Type='UserMulti'>" + _currentUser.Title + @"</Value>
                                             </Neq>
                                             <Geq>
                                                <FieldRef Name='MASAS_Expiration' />
                                                <Value Type='DateTime'><Today/></Value>
                                             </Geq>
                                          </And>
                                       </Where>
                                    </Query></View>";

            query.ViewXml = camlQueryXml;
            _notifications = notifications.GetItems( query );
            _context.Load( _notifications );
            _context.ExecuteQuery();

            Dispatcher.BeginInvoke( BindData );
        }

        /// <summary>
        /// Binds the data from the SP list to the Data Grid.
        /// </summary>
        private void BindData()
        {
            _notificationDS.Clear();

            foreach( ListItem listItem in _notifications )
            {
                NotificationMessage msg = new NotificationMessage();
                msg.Title = listItem["Title"].ToString();
                msg.Importance = listItem["MASAS_TrackingState"].ToString();
                msg.Updated = Convert.ToDateTime( listItem["Created"] ).ToLocalTime();
                msg.ItemIdentifier = Convert.ToInt32( listItem["ID"] );
                msg.ItemTitle = ( listItem["Item"] as FieldLookupValue ).LookupValue;

                _notificationDS.Add( msg );
            }

            dgNotifications.ItemsSource = _notificationDS;
        }

    }

}
